package org.orbis.spikezolt;

import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.shape.IShape;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;

import android.graphics.drawable.shapes.Shape;
import android.util.Log;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.Joint;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef;

public class Player extends Updater {
	// private BitmapTextureAtlas bitmapTextureAtlas;
	private AnimatedSprite spr;
	// private TiledTextureRegion playerTextureRegion;
	public int x, y = 0;

	SpikeZoltActivity sa;

	private Joint rJoint;

	private Rectangle r;

	public float horVel, verVel = 0;
	private float horSpeed = 45;

	public boolean canJump = false;
	public boolean jumping = false;
	public boolean leftReleased, rightReleased, upReleased = true;

	private PhysicsConnector physicsConnect;

	private float maxHor = 6.0f;

	public static FixtureDef bodyFixtureDef;
	public Body body; // The player
	public Body gBody; // The player's invisible body, attached groundSensor
						// fixture to itself

	public Player(SpikeZoltActivity bga, Scene scene, Engine engine,
			PhysicsWorld world, int x, int y) {
		this.x = x;
		this.y = y;
		this.sa = bga;

		spr = new AnimatedSprite(x, y, sa.texManager.TR_player);
		spr.setCurrentTileIndex(0);

		bodyFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
		bodyFixtureDef.restitution = 0.6f;

		body = PhysicsFactory.createCircleBody(world, spr,
				BodyType.DynamicBody, bodyFixtureDef);
		body.setUserData("player");

		bodyFixtureDef.density = 0;

		gBody = PhysicsFactory.createCircleBody(world, spr,
				BodyType.DynamicBody, bodyFixtureDef);
		gBody.setFixedRotation(true);

		FixtureDef groundsensorFixtureDef = PhysicsFactory.createFixtureDef(1,
				0.5f, 0.5f);

		PolygonShape polyShape = new PolygonShape();
		polyShape.setAsBox(4 * 0.02f, 4 * 0.02f, new Vector2(
				((spr.getWidth() / 2) - 16) * 0.02f,
				(spr.getHeight() - 8) * 0.02f), 0);

		groundsensorFixtureDef.shape = polyShape;
		groundsensorFixtureDef.density = 1.0f;
		groundsensorFixtureDef.isSensor = true;
		Fixture footSensorFixture = gBody.createFixture(groundsensorFixtureDef);
		footSensorFixture.setUserData("foot");

		final RevoluteJointDef revJointDef = new RevoluteJointDef();
		revJointDef.initialize(body, gBody, body.getWorldCenter());
		revJointDef.collideConnected = false;
		rJoint = world.createJoint(revJointDef);

		physicsConnect = new PhysicsConnector(spr, body, true, true);
		world.registerPhysicsConnector(physicsConnect);

		scene.attachChild(spr);
		spr.setZIndex(sa.PLAYER_DEPTH);
		scene.sortChildren();
	}

	@Override
	public void step() {

	}

	public Rectangle getRectangle() {
		r = new Rectangle(spr.getX(), spr.getY(), spr.getWidth(),
				spr.getHeight());
		return r;
	}

	public void leftPush(boolean button) {
		if (button) {
			horVel = -horSpeed;
			body.applyForce(new Vector2(horVel, 0), body.getPosition());
			if (body.getLinearVelocity().x <= -maxHor) {
				body.setLinearVelocity(-maxHor, body.getLinearVelocity().y);
			}
			// body.setLinearVelocity(horVel, body.getLinearVelocity().y);
		} else {
			// horVel = 0;
			// body.setLinearVelocity(horVel, body.getLinearVelocity().y);
		}
	}

	public void rightPush(boolean button) {
		if (button) {
			// just right
			horVel = horSpeed;
			body.applyForce(new Vector2(horVel, 0), body.getPosition());
			if (body.getLinearVelocity().x >= maxHor) {
				body.setLinearVelocity(maxHor, body.getLinearVelocity().y);
			}
			// body.setLinearVelocity(horVel, body.getLinearVelocity().y);
		} else {
			// horVel = 0;
			// body.setLinearVelocity(horVel, body.getLinearVelocity().y);
		}
	}

	public void upPush(boolean button) {
		if (button) {
			if (upReleased) {
				if (canJump) {
					canJump = false;
					verVel = -9.5f;
					sa.sndPlayer.sound_play(sa.sndPlayer.snd_bounce);
					body.setLinearVelocity(body.getLinearVelocity().x, verVel);
				}
			}
		} else {
			if (!canJump && body.getLinearVelocity().y < 0) {
				verVel = 0;
				body.setLinearVelocity(body.getLinearVelocity().x, verVel);
			}
		}

	}

	public void setPosition(int x, int y) {
		this.x = x;
		this.y = y;
		spr.setPosition(x, y);
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public AnimatedSprite getSprite() {
		return spr;
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		Log.d("Orbis", "player destroy");
		sa.mPhysicsWorld.unregisterPhysicsConnector(physicsConnect);
		//sa.scene.detachChild(spr);
		spr.detachSelf();
		sa.mPhysicsWorld.destroyBody(body);
		sa.mPhysicsWorld.destroyBody(gBody);
		rJoint = null;
	}
}